<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>canvas-demos</title>

    <style>
        canvas {
            margin: 0 auto;
            border: 2px solid #aaa;
            display: block;
        }
    </style>
</head>

<body>
<canvas id="cont" width="500px" height="500px">浏览器不支持</canvas>
<!--只能使用原生的js,如果让canvas左右居中使用display:block-->
<script>
    // 固定start获取画布
    const canvas = document.querySelector('#cont')
    // 获取画布上下文
    const ctx = canvas.getContext('2d')
    // 固定end

    const w = h = 500
    // 画文字
    drawText("LOVE U", w / 2, h / 2)
    // 获取像素点
    const copy = ctx.getImageData(0, 0, w, h);
    // 清除画布
    ctx.clearRect(0, 0, w, h)
    // 设置间隔
    const leap = 15
    const times = 100


    /**
     * 画实心小球
     * @param x
     * @param y
     * @param r
     * @param color
     */
    function drawCircle(x, y, r, color = '#000') {
        ctx.beginPath()
        ctx.arc(x, y, r, 0, Math.PI * 2, true)
        ctx.fillStyle = color
        ctx.fill()
    }

    /**
     * 画填充文字
     * @param text
     * @param x
     * @param y
     */
    function drawText(text, x, y) {
        ctx.font = '300px 微软雅黑'
        ctx.fillStyle = '#000'
        ctx.textAlign = 'center'
        ctx.textBaseline = 'middle'
        ctx.fillText(text, x, y, w)
    }

    // 画带颜色填充文字
    function drawFillText(text, x, y, color) {
        ctx.font = '12px 微软雅黑'
        ctx.fillStyle = color
        ctx.textAlign = 'center'
        ctx.textBaseline = 'middle'
        ctx.fillText(text, x, y, w)
    }

    /**
     * 获取随机值
     * @param inputNumber
     */
    function randomNum(inputNumber) {
        return Math.random() * inputNumber
    }

    function Ball(xEnd, yEnd) {
        // 起始位置随机
        this.xStart = randomNum(w)
        this.yStart = randomNum(h)
        // 结束位置,固定
        this.xEnd = xEnd
        this.yEnd = yEnd

        // 计算运动速度,通过起始点和结束点
        this.xSpeed = (this.xEnd - this.xStart) / times
        this.ySpeed = (this.yEnd - this.yStart) / times

        // 小球运动的中心点
        this.x = this.xStart
        this.y = this.yStart
        // 设置半径和颜色
        this.r = 5
        this.color = '#f00'

        // 设置填充文字
        this.text = '♥'
    }

    Ball.prototype.show = function () {
        // 动态计算每次运动的坐标位置
        this.x += this.xSpeed
        this.y += this.ySpeed
        //drawCircle(this.x, this.y, this.r, this.color)
        drawFillText(this.text, this.x, this.y, this.color)
    }


    const ballArr = []
    // 筛选有效像素点
    for (let y = 0; y < h; y += leap) {
        for (let x = 0; x < w; x += leap) {
            const index = x + y * w // 像素索引
            const a = copy.data[index * 4 + 3]
            if (a > 128) {
                // 不动的话就是下面代码
                // drawCircle(x, y, 5, '#f00')
                const ball = new Ball(x, y)
                // 存入数组
                ballArr.push(ball)
            }
        }
    }

    let count = 0
    const timer = setInterval(function () {
        count++
        //清除画布
        ctx.clearRect(0, 0, w, h)
        for (const ballArrElement of ballArr) {
            ballArrElement.show()
        }
        if (count === times) {
            clearInterval(timer)
        }
    }, 50)
</script>
</body>
</html>
